package com.ygqh.baby.handler;

import com.ygqh.baby.ao.PromotionType;
import com.ygqh.baby.ao.SalesPlatform;
import com.ygqh.baby.model.CarPackPriceResult;
import com.ygqh.baby.model.CarPricesResult;
import com.ygqh.baby.model.YgCouponModel;
import com.ygqh.baby.model.YgShoppingCarModel;
import com.ygqh.baby.service.*;
import com.ygqh.baby.utils.CarComparator;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 〈〉
 *
 * @author guohao
 * @date 2018/12/12 16:57
 * @since 1.0.0
 */
@Component
public class ShoppingCarHandler extends BaseShoppingCarHandler {

    @Autowired
    private YgUserService ygUserService;
    @Autowired
    private YgOrderService ygOrderService;
    @Autowired
    private YgCouponService ygCouponService;
    @Autowired
    private YgBmdismService ygBmdismService;
    @Autowired
    private YgShoppingCarService ygShoppingCarService;


    public CarPricesResult getCarPrices(List<YgShoppingCarModel> carList, String formId, Long couponDetailId,
                                        SalesPlatform salesPlatform) {
        if (CollectionUtils.isEmpty(carList)) {
            return null;
        }
        Long userId = carList.get(0).getUserId();
        //设置多买多折标记
        ygBmdismService.getBestBmdism(carList);
        ygShoppingCarService.doNewCusBussness(carList);
        CarPricesResult carPricesResult = new CarPricesResult();
        //多买多折优惠
        BigDecimal bmdisPrice = getCarBmdisPrice(carList);
        //获取自选包，新客，特例品金额
        CarPackPriceResult packAndNewCustomDisPrice = getPackAndNewCustomDisAndSpecialPrice(carList);
        BigDecimal productPrice = packAndNewCustomDisPrice.getProductPrice();
        carPricesResult.setNewCustomDisPrice(packAndNewCustomDisPrice.getNewCustomDisPrice());
        carPricesResult.setPackDisPrice(packAndNewCustomDisPrice.getPackDisPrice());
        carPricesResult.setSpecialPrice(packAndNewCustomDisPrice.getSpecialPrice());
        carPricesResult.setBmdisPrice(bmdisPrice);
        carPricesResult.setPackList(packAndNewCustomDisPrice.getCarList());


        BigDecimal manjianValidPrice = productPrice.subtract(carPricesResult.getNewCustomDisPrice())
                .subtract(carPricesResult.getPackDisPrice());

        //满减
        Map<String, Object> manJian = ygOrderService.getManJianPrice(manjianValidPrice, formId, userId);
        Boolean useCoupon = (Boolean) manJian.get("useCoupon");
        BigDecimal manJianPrice = (BigDecimal) manJian.get("manjianPrice");
        carPricesResult.setManJianPrice(manJianPrice);

        // 验证优惠券禁用设置
        YgCouponModel couponModel = null;
        if (useCoupon && !validateDisableCouponFromRedis()) {
            BigDecimal couponValidPrice = manjianValidPrice.subtract(carPricesResult.getSpecialPrice());
            if (couponValidPrice.compareTo(BigDecimal.ZERO) > 0) {
                couponModel = ygCouponService.findCouponForPayV2(userId, couponDetailId, couponValidPrice,
                        false, carList, salesPlatform);
            }
        }
        carPricesResult.setCoupon(couponModel);
        carPricesResult.setUseCoupon(useCoupon);
        carPricesResult.setProductPrice(productPrice);


        // 当商品金额-新客及自选包优惠金额 - 满减金额 -优惠券金额 < 0
        BigDecimal expressValidPrice = manjianValidPrice;
        if (couponModel != null) {
            expressValidPrice = manjianValidPrice.subtract(couponModel.getFaceValue());
        }
        if (expressValidPrice.compareTo(BigDecimal.ZERO) < 0) {
            expressValidPrice = BigDecimal.ZERO;
        }
        //运费
        BigDecimal expressPrice = ygOrderService.getExpressPrice(expressValidPrice, userId, salesPlatform);
        carPricesResult.setExpressPrice(expressPrice);
        return carPricesResult;
    }

    /**
     * 获取购物车多买多折优惠
     *
     * @param carList 购物车
     * @return BigDecimal
     */
    private BigDecimal getCarBmdisPrice(List<YgShoppingCarModel> carList) {
        return carList.stream().filter(car -> PromotionType.Bmdism.equals(car.getSalesType()))
                .map(car -> (car.getSalesPrice().subtract(car.getRealSalesPrice())).multiply(new BigDecimal(car.getQuantity())))
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }


    /**
     * 获取购物车自选包优惠金额、新客优惠金额、特例品金额
     * <p>
     * 重构时可以将自选包金额与新客金额分离出来
     *
     * @param carList 购物车列表
     * @return CarPackPriceResult
     */
    public CarPackPriceResult getPackAndNewCustomDisAndSpecialPrice(List<YgShoppingCarModel> carList) {
        Assert.notEmpty(carList, "购物车数据为空");
        Long userId = carList.get(0).getUserId();
        Boolean newCustom = ygUserService.isNewCustom(userId);

        BigDecimal productPrice = carList.stream().map(carModel -> carModel.getRealSalesPrice().multiply(new BigDecimal(carModel.getQuantity())))
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        //获取非自选包商品女王价金额
        BigDecimal newCustomDisPrice = getUnPackUnBmdismCarNewCustomDisPrice(carList, newCustom);
        BigDecimal specialPrice = getUnPackCarSpecialPrice(carList, newCustom);
        BigDecimal vipDisPrice = getUnPackVipDisPrice(carList);


        //获取所有自选包商品并按价格倒序排列
        List<YgShoppingCarModel> packCarList = carList.stream().filter(car -> car.getPackId() != null && car.getPackId() > 0
                && PromotionType.Ordinary.equals(car.getSalesType())).sorted(new CarComparator()).collect(Collectors.toList());

        //将所有自选包商品（按数量一一拆分）放到一个桶里，

//        List<YgShoppingCarModel> packSpitCarList = setPackCarToBucket(packCarList);

        //自选包总优惠
        BigDecimal packDisPrice = BigDecimal.ZERO;
        //存放满足自选包活动的购物车id
        Map<Long, Long> packCarIdMap = new HashMap<>(packCarList.size());
        Map<Long, List<YgShoppingCarModel>> packMap = packCarList.stream().collect(Collectors.groupingBy(YgShoppingCarModel::getPackId));
        for (Map.Entry<Long, List<YgShoppingCarModel>> entry : packMap.entrySet()) {
            CarPackPriceResult carPackPriceResult = doEachGroupPack(entry.getValue(), newCustom);
            specialPrice = specialPrice.add(carPackPriceResult.getSpecialPrice());
            packDisPrice = packDisPrice.add(carPackPriceResult.getPackDisPrice());
            vipDisPrice = vipDisPrice.add(carPackPriceResult.getVipDisPrice());
            newCustomDisPrice = newCustomDisPrice.add(carPackPriceResult.getNewCustomDisPrice());
            packCarIdMap.putAll(carPackPriceResult.getCarIdMap());
        }

        List<YgShoppingCarModel> packList = new ArrayList<>();
        for (YgShoppingCarModel carModel : carList) {
            Long quantity = packCarIdMap.get(carModel.getId());
            if (quantity != null) {
                YgShoppingCarModel clone = carModel.clone();
                clone.setQuantity(quantity);
                packList.add(clone);
            }
        }

        CarPackPriceResult result = new CarPackPriceResult();
        result.setPackDisPrice(packDisPrice);
        result.setSpecialPrice(specialPrice);
        result.setNewCustomDisPrice(newCustomDisPrice);
        result.setCarIdMap(packCarIdMap);
        result.setCarList(packList);
        result.setVipDisPrice(vipDisPrice);
        result.setProductPrice(productPrice);
        return result;

    }

    private List<YgShoppingCarModel> setPackCarToBucket(List<YgShoppingCarModel> packCarList) {
        List<YgShoppingCarModel> packSpitCarList = new ArrayList<>();
        for (YgShoppingCarModel car : packCarList) {
            for (long i = 0; i < car.getQuantity(); i++) {
                YgShoppingCarModel clone = car.clone();
                clone.setQuantity(1L);
                packSpitCarList.add(clone);
            }
        }
        return packSpitCarList;

    }

    /**
     * 获取购物车非自选包vip优惠金额
     *
     * @param carList 购物车列表
     */
    private BigDecimal getUnPackVipDisPrice(List<YgShoppingCarModel> carList) {
        return carList.stream().map(carModel -> {
            BigDecimal vipDisPrice = BigDecimal.ZERO;
            if (PromotionType.Ordinary.equals(carModel.getSalesType()) && carModel.getPackId() < 1) {
                vipDisPrice = carModel.getRealSalesPrice().subtract(carModel.getVipPrice()).multiply(new BigDecimal(carModel.getQuantity()));
            } else if (PromotionType.Bmdism.equals(carModel.getSalesType())) {
                vipDisPrice = carModel.getRealSalesPrice().subtract(carModel.getVipPrice()).multiply(new BigDecimal(carModel.getQuantity()));
            }
            return vipDisPrice;
        }).reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    /**
     * 获取非自选包商品 特例品金额
     *
     * @param carList   购物车列表
     * @param newCustom 新客
     * @return BigDecimal
     */
    private BigDecimal getUnPackCarSpecialPrice(List<YgShoppingCarModel> carList, Boolean newCustom) {
        BigDecimal specialPrice = BigDecimal.ZERO;
        for (YgShoppingCarModel car : carList) {
            BigDecimal realSalesPrice = car.getRealSalesPrice();
            if (car.getIsSpecial() && car.getPackId() == 0 && PromotionType.Ordinary.equals(car.getSalesType())) {
                if (newCustom && car.getNewCustomPrice().compareTo(BigDecimal.ZERO) > 0) {
                    specialPrice = specialPrice.add(realSalesPrice.multiply(new BigDecimal(car.getQuantity() - 1)));
                    specialPrice = specialPrice.add(car.getNewCustomPrice());
                } else {
                    specialPrice = specialPrice.add(realSalesPrice.multiply(new BigDecimal(car.getQuantity())));
                }

            }
        }
        return specialPrice;
    }

    /**
     * 获取非自选包商品新客优惠价
     *
     * @param carList 购物车列表
     */
    private BigDecimal getUnPackUnBmdismCarNewCustomDisPrice(List<YgShoppingCarModel> carList, Boolean newCustom) {

        //存放新客优惠价的池子。 同一sku 只有一件享受新客优惠
        Map<Long, BigDecimal> newCusMap = new HashMap<>(carList.size());
        carList.stream().filter(car -> PromotionType.Ordinary.equals(car.getSalesType()) && car.getPackId() == 0).forEach(car -> {
            //新客优惠
            if (newCustom && !newCusMap.containsKey(car.getSkuId())) {
                BigDecimal disPrice = getNewCustomDisPrice(car);
                newCusMap.put(car.getSkuId(), disPrice);
            }
        });
        return newCusMap.values().stream().reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    /**
     * 处理每一组自选包
     */
    private CarPackPriceResult doEachGroupPackByBucket(List<YgShoppingCarModel> list, Boolean newCustom) {

        //存放满足自选包活动的购物车id
        Map<Long, Long> packCarIdMap = new HashMap<>(list.size());
        Long productAmount = list.get(0).getProductAmount();
        Boolean useCoupon = list.get(0).getUseCoupon();
        Boolean cumulative = list.get(0).getCumulative();
        BigDecimal packPrice = list.get(0).getPackPrice();
        BigDecimal packVipPrice = list.get(0).getPackVipPrice();
        BigDecimal totalPackPrice;
        BigDecimal totalPackVipPrice;
        BigDecimal packSkuTotalPrice = BigDecimal.ZERO;
        BigDecimal specialPrice = BigDecimal.ZERO;
        BigDecimal newCustomDisPrice = BigDecimal.ZERO;

        BigDecimal vipDisPrice = BigDecimal.ZERO;
        //存放新客优惠价的池子。 同一sku 只有一件享受新客优惠
        Map<Long, BigDecimal> newCusMap = new HashMap<>(list.size());
        //累计次数
        Long cumulativeCount = 1L;
        if (cumulative) {
            cumulativeCount = list.size() / productAmount;
        } else if (list.size() < productAmount) {
            cumulativeCount = 0L;
        }
        totalPackPrice = packPrice.multiply(new BigDecimal(cumulativeCount));
        totalPackVipPrice = packVipPrice.multiply(new BigDecimal(cumulativeCount));
        Long count = cumulativeCount * productAmount;

        //满足自选包商品平均售价
        BigDecimal sharePrice = packPrice.divide(new BigDecimal(productAmount), 2, BigDecimal.ROUND_HALF_UP);
        for (int i = 0; i < list.size(); i++) {
            YgShoppingCarModel car = list.get(i);
            if (i < count) {
                if (!useCoupon || car.getIsSpecial()) {
                    specialPrice = specialPrice.add(sharePrice);
                }
                Long quantity = packCarIdMap.get(car.getId());
                if (quantity == null) {
                    quantity = 0L;
                }
                quantity++;
                packCarIdMap.put(car.getId(), quantity);

                packSkuTotalPrice = packSkuTotalPrice.add(car.getRealSalesPrice());

            } else {
                BigDecimal subVipDisPrice = car.getRealSalesPrice().subtract(car.getVipPrice()).multiply(new BigDecimal(car.getQuantity()));
                vipDisPrice = vipDisPrice.add(subVipDisPrice);
                //新客优惠
                if (newCustom && !newCusMap.containsKey(car.getSkuId())) {
                    BigDecimal disPrice = getNewCustomDisPrice(car);
                    newCusMap.put(car.getSkuId(), disPrice);
                    newCustomDisPrice = newCustomDisPrice.add(disPrice);
                    if (car.getIsSpecial()) {
                        specialPrice = specialPrice.add(car.getNewCustomPrice());
                    }
                } else if (car.getIsSpecial()) {
                    //不参与自选包的特例品金额
                    specialPrice = specialPrice.add(car.getRealSalesPrice());
                }
            }
        }
        vipDisPrice = vipDisPrice.add(totalPackPrice.subtract(totalPackVipPrice));
        BigDecimal packDisPrice = BigDecimal.ZERO;
        if (packSkuTotalPrice.compareTo(totalPackPrice) > 0) {
            packDisPrice = packSkuTotalPrice.subtract(totalPackPrice);
        }
        CarPackPriceResult result = new CarPackPriceResult();
        result.setPackDisPrice(packDisPrice);
        result.setSpecialPrice(specialPrice);
        result.setNewCustomDisPrice(newCustomDisPrice);
        result.setCarIdMap(packCarIdMap);
        result.setVipDisPrice(vipDisPrice);
        return result;

    }

    private CarPackPriceResult doEachGroupPack(List<YgShoppingCarModel> list, Boolean newCustom) {

        //存放满足自选包活动的购物车id
        Map<Long, Long> packCarIdMap = new HashMap<>(list.size());
        Long productAmount = list.get(0).getProductAmount();
        Boolean useCoupon = list.get(0).getUseCoupon();
        Boolean cumulative = list.get(0).getCumulative();
        BigDecimal packPrice = list.get(0).getPackPrice();
        BigDecimal packVipPrice = list.get(0).getPackVipPrice();
        BigDecimal totalPackPrice;
        BigDecimal totalPackVipPrice;
        BigDecimal packSkuTotalPrice = BigDecimal.ZERO;
        BigDecimal specialPrice = BigDecimal.ZERO;
        BigDecimal newCustomDisPrice = BigDecimal.ZERO;

        BigDecimal vipDisPrice = BigDecimal.ZERO;
        //存放新客优惠价的池子。 同一sku 只有一件享受新客优惠
        Map<Long, BigDecimal> newCusMap = new HashMap<>(list.size());
        //累计次数
        Long cumulativeCount = 1L;
        Long buyCount = list.stream().map(YgShoppingCarModel::getQuantity).reduce(0L, (a, b) -> a + b);
        if (cumulative) {
            cumulativeCount = buyCount / productAmount;
        } else if (buyCount.compareTo(productAmount) < 0) {
            cumulativeCount = 0L;
        }
        Long count = cumulativeCount * productAmount;
        totalPackPrice = packPrice.multiply(new BigDecimal(cumulativeCount));
        totalPackVipPrice = packVipPrice.multiply(new BigDecimal(cumulativeCount));

        //满足自选包商品平均售价
        BigDecimal sharePrice = packPrice.divide(new BigDecimal(productAmount), 2, BigDecimal.ROUND_HALF_UP);
        BigDecimal lastPackPrice = totalPackPrice;
        Long lastCount = count;
        for (YgShoppingCarModel carModel : list) {
            Long originAmount = 0L;
            Long quantity = carModel.getQuantity();
            if (lastCount > 0) {
                Long carId = carModel.getId();
                long tempCount = lastCount - quantity;
                Long packAmount = 0L;
                if (tempCount >= 0) {
                    packAmount = quantity;
                } else {
                    packAmount = lastCount;
                }
                originAmount = quantity - packAmount;
                packCarIdMap.put(carId, packAmount);
                lastCount = tempCount;

                if (!useCoupon || carModel.getIsSpecial()) {
                    if (lastCount <= 0) {
                        specialPrice = specialPrice.add(lastPackPrice);
                    } else {
                        BigDecimal subPackPrice = sharePrice.multiply(new BigDecimal(packAmount));
                        specialPrice = specialPrice.add(subPackPrice);
                        lastPackPrice = lastPackPrice.subtract(subPackPrice);
                    }
                }
                packSkuTotalPrice = packSkuTotalPrice.add(carModel.getRealSalesPrice().multiply(new BigDecimal(packAmount)));
            } else {
                originAmount = quantity - lastCount;
            }
            if (originAmount > 0) {
                //普通商品
                BigDecimal subVipDisPrice = carModel.getRealSalesPrice().subtract(carModel.getVipPrice()).multiply(new BigDecimal(carModel.getQuantity()));
                vipDisPrice = vipDisPrice.add(subVipDisPrice);
                //新客优惠
                if (newCustom && !newCusMap.containsKey(carModel.getSkuId())) {
                    BigDecimal disPrice = getNewCustomDisPrice(carModel);
                    newCusMap.put(carModel.getSkuId(), disPrice);
                    newCustomDisPrice = newCustomDisPrice.add(disPrice);
                    if (carModel.getIsSpecial()) {
                        specialPrice = specialPrice.add(carModel.getNewCustomPrice().multiply(new BigDecimal(originAmount - 1)));
                    }
                } else if (carModel.getIsSpecial()) {
                    //不参与自选包的特例品金额
                    specialPrice = specialPrice.add(carModel.getRealSalesPrice().multiply(new BigDecimal(originAmount)));
                }
            }
        }
        vipDisPrice = vipDisPrice.add(totalPackPrice.subtract(totalPackVipPrice));
        BigDecimal packDisPrice = BigDecimal.ZERO;
        if (packSkuTotalPrice.compareTo(totalPackPrice) > 0) {
            packDisPrice = packSkuTotalPrice.subtract(totalPackPrice);
        }
        CarPackPriceResult result = new CarPackPriceResult();
        result.setPackDisPrice(packDisPrice);
        result.setSpecialPrice(specialPrice);
        result.setNewCustomDisPrice(newCustomDisPrice);
        result.setCarIdMap(packCarIdMap);
        result.setVipDisPrice(vipDisPrice);
        return result;

    }

    /**
     * 获取新客优惠价
     *
     * @param car 购物车
     * @return BigDecimal
     */
    private BigDecimal getNewCustomDisPrice(YgShoppingCarModel car) {
        if (PromotionType.Ordinary.equals(car.getSalesType()) && car.getNewCustomPrice() != null
                && car.getNewCustomPrice().compareTo(BigDecimal.ZERO) > 0) {

            return car.getRealSalesPrice().subtract(car.getNewCustomPrice());
        }
        return BigDecimal.ZERO;
    }


}
